package base

/**
 * Created by Darkness1m on 2017/6/5.
 */
//定义一个可以传入lambda函数的方法
fun lambdaT(name: String,body: () -> Int){

}
fun lambdaT2(name: String,body: (Int) -> Int){

}
fun main14(args: Array<String>) {
    base.lambdaT("张三", { 1 })//1 相当于这个lambda return 1
    //等同于
    base.lambdaT("张三") { 1 }//当最后一个参数为lambda表达式时,可以提到括号外面来

    base.lambdaT2("李四") { it + 5 }//当参数只有一个的时候,系统自动声明为it,it+5是返回值


    val sum: (Int,Int) -> Int = {x,y -> x + y}

    val sub: (Int,Int,Int) -> Int = {_,x,y -> x-y}//对于没有使用到的参数,可以用"_"代替

    //使用限定的返回语法从lambda显式返回值
    var s = listOf<Int>(1,2,3,4,5)
    s.filter {
        val shouldFilter = it > 0
        shouldFilter
    }
    //等同于:
    s.filter{
        val shouldFilter = it > 0
        return@filter shouldFilter
    }
    base.sum2(2)

    base.sum2(1, 2)//????
}

val sum2 = fun Int.(other: Int): Int = this + other

//非局部返回
fun retNonPart(){
    base.inlFun {
        return//内联的,就是说这里返回了就是整个函数返回了,不只是lambda
    }
    base.nonLineFun {
        //        return//不允许这样返回
        return@nonLineFun//TODO 还不太懂..
    }
}

inline fun inlFun(body: () -> Unit){}
fun nonLineFun(body: () -> Unit){}

//reified具体化参数,该修饰符只能与inline搭配使用,否则编译错误
inline fun <reified T> reified(): T?{return B() as T?}

//不用内联,调用的时候传参比较麻烦
fun <T> findType(clazz: Class<T>): T?{
    var s = B()
    if(clazz.isInstance(s))//判断类型的时候就不能使用 is  as  之类的了
        @Suppress("UNCHECKED_CAST")
        return s as T?
    return null
}
inline fun <reified T> findTypeI(): T?{
    var s = B()
    if(s!=null&&s is T)//这里就可以使用is  as等
        return s
    return null
}

inline fun <reified T> membersOf() = T::class.members//不包括constructor,包括方法/变量等
fun main15(args: Array<String>) {
    base.findType(B::class.java)//class.java是java类的引用,kotlin是B::class->KClass类型
    base.findTypeI<B>()//内联之后就可以这样写
    base.membersOf<StringBuilder>().joinToString("\n")//调用其方法
}

fun main(args: Array<String>) {
//sampleStart
    val lazySeq = kotlin.coroutines.experimental.buildSequence {
        print("START ")
        for (i in 1..5) {
            yield(i)
            print("STEP ")
        }
        print("END")
    }
// 输出序列的前三个元素
    lazySeq.take(3).forEach { print("$it ") }
//sampleEnd

    val lazySeq2 = kotlin.coroutines.experimental.buildSequence {
        yield(0)
        yieldAll(1..10)
    }
    lazySeq2.forEach { print("$it ") }
}
